<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript" src="../jsunit/app/jsUnitCore.js"></script>
    <script type="text/javascript" src="../../src/objx.test.js"></script>
    <script type="text/javascript" src="../../src/objx.js"></script>
    <script type="text/javascript">
    
    	var mockedMethodArgs = null;
    	var counter = 0;
    	
    	
    	function test_notifyMethodWithArguments()
		{
		
			counter = 0;

			var Dog = Class({
    			onBark: Event(),
    			onWag: Event()
    		});
    		
    		var myDog = new Dog();
    		
    		var callback = function(context, num){ 
    			counter += num; };
    		
    		myDog.observe("onBark", callback);
    		
    		// notify the event
    		// Ideally I want to be able to do this:
    		// myDog.onBark(10);
    		// but instead I have to do this:
    		myDog.notify("onBark", 10);
			
			try
			{
				assertEquals("Callback not called with correct arguments", 10, counter);
			}
			catch(e)
			{
				throw e
			}
		
		}



    	function test_namespace(){
    	
    		assertNotUndefined("objx.event is undefined", objx.event);
   
			assertNotUndefined("objx.Event", objx.Event);
			assertEquals("objx.Event not an objx Class.", "c", objx.Event.objx.t);
	
		}

		function test_classEventType()
		{
		
			var e = Event();

			assertNotUndefined("e.objx", e.objx);
    		assertEquals("e.objx.e (type) should be e (event)", "e", e.objx.t);
		
		}

		function test_classEventsCachedInKlass()
		{
		
			var Dog = Class({
    			onBark: Event()
    		});
    	
    		// make sure the event is saved
    		assertNotUndefined("Dog.events", Dog.events);

			assertEquals("Dog.events expected to have one event.", 1, Dog.events.length);

		}
			
		function test_observeMethodCalled()
		{
		
			counter = 0;

			var Dog = Class({
    			onBark: Event()
    		});
    		
    		var myDog = new Dog();
    		var callback = function(){ counter++; };
    		
    		// ideally I want to be able to do this:
    		//myDog.onBark(callback);
    		// but instead I have to do this:
    		myDog.observe("onBark", callback);
    		
    		// notify the event
    		objx.notify(myDog, "onBark");
			
			try
			{
				assertEquals("Callback not called", 1, counter);
			}
			catch(e)
			{
				throw e
			}
			
		}
		
		function test_directObserveMethodCalled()
		{
		
			counter = 0;

			var Dog = Class({
    			onBark: Event()
    		});
    		
    		var myDog = new Dog();
    		var callback = function(){ counter++; };
    		
    		assertNotUndefined("myDog.observe_onBark", myDog.observe_onBark);
    		
    		// this should also work:
    		myDog.observe_onBark(callback);
    		// but instead I have to do this
    		//myDog.observe("onBark", callback);
    		
    		// notify the event
    		objx.notify(myDog, "onBark");
			
			try
			{
				assertEquals("Callback not called", 1, counter);
			}
			catch(e)
			{
				throw e
			}
			
		}
		
		function test_notifyMethodCalled()
		{
		
			counter = 0;

			var Dog = Class({
    			onBark: Event()
    		});
    		
    		var myDog = new Dog();
    		var callback = function(){ counter++; };
    		
    		myDog.observe("onBark", callback);
    		
    		// notify the event
    		//myDog.onBark();
    		myDog.notify("onBark");
			
			try
			{
				assertEquals("Callback not called", 1, counter);
			}
			catch(e)
			{
				throw e
			}
		
		}
		

		
		function test_notifyEventDirectFunction()
		{
		
			counter = 0;

			var Dog = Class({
    			onBark: Event()
    		});
    		
    		var myDog = new Dog();
    		var callback = function(context, num){ counter += num; };
    		
    		myDog.observe("onBark", callback);
    		
    		// notify the event
    		myDog.notify_onBark(10);
    		//myDog.notify("onBark", 10);
			
			try
			{
				assertEquals("Callback not called with correct arguments", 10, counter);
			}
			catch(e)
			{
				throw e
			}
		
		}
				
    	function test_classEventDefinition(){
    	
    		var Dog = Class({
    			onBark: Event()
    		});
    	    		
    		assertNotUndefined("Event definition did not generate Dog.prototype.onBark() function.", Dog.prototype.onBark);
    	
    		assertEquals("Dog.prototype.onBark expected to be a function", "function", typeof Dog.prototype.onBark);
    	
    		// test to make sure the other methods are there
    		assertNotUndefined("Dog.prototype.notify_onBark", Dog.prototype.notify_onBark);
    		assertNotUndefined("Dog.prototype.observe_onBark", Dog.prototype.observe_onBark);
    	
    	}
    	
    	function test_classEventsInherited()
    	{
    	
    		// tests to ensure the events are inherited correctly to 
    		// sub-classes
    		
    		counter = 0;
    		
    		var Animal = Class({
    			onMove: Event()
    		});
    		
    		var Dog = Class(Animal, {
    			onBark: Event()
    		});
    		
    		// make sure Dog gets all events
    		assertNotUndefined("Dog.prototype.onBark", Dog.prototype.onBark);
    		assertNotUndefined("Dog.prototype.onMove", Dog.prototype.onMove);

			// ensure they are all functions
			assertEquals("function", typeof Dog.prototype.onBark);
			assertEquals("function", typeof Dog.prototype.onMove);
			
			// create an instance of both classes
			var myAnimal = new Animal();
			var myDog = new Dog();
			
			assertNotUndefined("myAnimal.onMove", myAnimal.onMove);
			assertNotUndefined("myDog.onMove", myDog.onMove);
			
			// test to ensure the methods behave as expected in 
			// a sub-class
			myDog.onMove(function(){
				counter++;
			});

			myDog.onMove();
			
			assertEquals("Callback of sub-class event not called", 1, counter);
			
			myDog.onMove();
			
			assertEquals("Callback of sub-class event not called correctly", 2, counter);
			
    	}
</script>
    </script>
</head>
<body>
</body>
</html>